﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using StockShark.Models;
using StockShark.ViewModels;
using System.Web.Security;

namespace StockShark.Controllers
{ 
    
    public class BrokerageAccountController : Controller
    {
        private StockSharkDB db = new StockSharkDB();

        [Authorize]
        public ViewResult Index()
        {
            return View(GetAccountsForCurrentUser());
        }

        [Authorize]
        public ActionResult Details(string name)
        {
            List<BrokerageAccount> accountList = GetAccountsForCurrentUser();
            BrokerageAccount ba;
            try
            {
                ba = accountList.Single(r => r.Name == name);
            }
            catch (Exception e)
            {
                return HttpNotFound();
            }
            ba.TotalValue = ba.Balance;
            foreach (var oi in ba.OwnedInstruments)
            {
                ba.TotalValue += oi.TotalValue;
            }
            db.SaveChanges();

            return View(ba);
        }

        [Authorize]
        public ActionResult Charts(string name, string period = "week")
        {
            List<BrokerageAccount> accountList = GetAccountsForCurrentUser();
            BrokerageAccount ba;
            try
            {
                ba = accountList.Single(r => r.Name == name);
            }
            catch (Exception e)
            {
                return HttpNotFound();
            }
            DateTime start;
            ViewBag.PeriodSelectList = PeriodList.GetSelectList(period);
            var accountValues = db.AccountValues.Where(r => r.BrokerageAccountId == ba.Id);
            if (period.ToLower().Equals("all"))
            {
                if (accountValues.Count() > 0)
                    start = accountValues.Min(r => r.Timestamp);
                else
                    start = DateTime.Today.AddDays(-1);
            }
            else
            {
                try
                {
                    start = PeriodList.GetStartDate(period);
                }
                catch (NotSupportedException e)
                {
                    return HttpNotFound();
                }
            }

            List<AccountValue> vals = accountValues
                .OrderBy(r => r.Timestamp)
                .ToList();
            BAChartsData chartsData = new BAChartsData { Values = vals, BrokerageAccount = ba, StartDate = start };
            chartsData.CalculateValues();
            return View(chartsData);
        }

        [Authorize]
        public ActionResult Orders(string name)
        {
            List<BrokerageAccount> accountList = GetAccountsForCurrentUser();
            BrokerageAccount ba;
            try
            {
                ba = accountList.Single(r => r.Name == name);
            }
            catch (Exception e)
            {
                return HttpNotFound();
            }
            return View(ba);
        }

        [Authorize]
        public ActionResult History(string name)
        {
            List<BrokerageAccount> accountList = GetAccountsForCurrentUser();
            BrokerageAccount ba;
            try
            {
                ba = accountList.Single(r => r.Name == name);
            }
            catch (Exception e)
            {
                return HttpNotFound();
            }
            return View(ba);
        }

        [Authorize]
        public ActionResult Create()
        {
            BrokerageAccount ba = new BrokerageAccount { UserId = (Guid)Membership.GetUser().ProviderUserKey };
            return View(ba);
        } 

        [Authorize]
        [HttpPost]
        public ActionResult Create(BrokerageAccount ba)
        {
            ba.CreationDate = DateTime.Now;
            ba.Balance = 50000.00M;
            ba.TotalValue = 50000.00M;
            if (ModelState.IsValid && ba.UserId == (Guid)Membership.GetUser().ProviderUserKey)
            {
                db.BrokerageAccounts.Add(ba);                
                db.SaveChanges();
                return RedirectToAction("Index");  
            }
            ba.UserId = (Guid)Membership.GetUser().ProviderUserKey;
            return View(ba);
        }

        [Authorize]
        public ActionResult Edit(string name)
        {
            List<BrokerageAccount> accountList = GetAccountsForCurrentUser();
            BrokerageAccount ba;
            try
            {
                ba = accountList.Single(r => r.Name == name);
            }
            catch (Exception e)
            {
                return HttpNotFound();
            }
            return View(ba);
        }

        [Authorize]
        [HttpPost]
        public ActionResult Edit(BrokerageAccount ba)
        {
            if (ModelState.IsValid && ba.UserId == (Guid)Membership.GetUser().ProviderUserKey)
            {
                db.Entry(ba).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(ba);
        }

        [Authorize]
        public ActionResult Delete(string name)
        {
            List<BrokerageAccount> accountList = GetAccountsForCurrentUser();
            BrokerageAccount ba;
            try
            {
                ba = accountList.Single(r => r.Name == name);
            }
            catch (Exception e)
            {
                return HttpNotFound();
            }
            return View(ba);
        }

        [Authorize]
        [HttpPost]
        public ActionResult Delete(int id)
        {            
            BrokerageAccount ba = db.BrokerageAccounts.Find(id);
            if (ba.UserId == (Guid)Membership.GetUser().ProviderUserKey)
            {
                db.BrokerageAccounts.Remove(ba);
                db.SaveChanges();
            }
            return RedirectToAction("Index");
        }

        [ChildActionOnly]
        public ActionResult AccountListForMenu()
        {
            List<BrokerageAccount> accountList = GetAccountsForCurrentUser();
            return PartialView("_AccountListForMenu", accountList);
        }

        private List<BrokerageAccount> GetAccountsForCurrentUser()
        {
            if (Request.IsAuthenticated)
            {
                Guid userId = (Guid)Membership.GetUser().ProviderUserKey;
                return db.BrokerageAccounts.Where(r => r.UserId == userId).ToList();
            }
            else
                return null;
        }

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }
    }
}